package org.jvm.instruction.references;

import org.jvm.instruction.base.*;
import org.jvm.rtda.Object;
import org.jvm.rtda.heap.*;
import org.jvm.rtda.heap.symref.ClassRef;
import org.jvm.rtda.thread.Frame;

/**
 * 创建对象实例，分配空间
 *
 * @author 海燕
 * @date 2023/2/6
 */
public class NEW extends Index16Instruction {


    /**
     * 指令操作数含义为类常量池索引
     *
     * @param frame
     */
    @Override
    public void execute(Frame frame) {
        //从常量池获取一个类符号引用
        ConstantPool constantPool = frame.getMethod().getKlass().getConstantPool();
        ClassRef classRef = (ClassRef) constantPool.getConstant(this.index);
        //解析这个类符号引用
        Klass klass = classRef.resolvedClass(frame.getThread());
        //执行类初始化
        InstructionUtil.initClass(frame.getThread(), klass);
        //接口和抽象类无法实例化
        if (klass.isInterface() || klass.isAbstract()) {
            throw new RuntimeException("接口和抽象类无法实例化");
        }
        //给这个类符合引用创建一个实例
        Object object = klass.newObject();
        //将新建的实例引用压操作数栈
        frame.getOperandStack().pushRef(object);
    }
}
